package com.fingard.xml;

import java.io.File;
import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

public class DomHelper {

	/**
	 * 解析XML
	 *
	 * @param xmlContent
	 * @return
	 * @throws SAXException
	 * @throws IOException
	 * @throws ParserConfigurationException
	 */
	public static Document parseDocumentByString(String xmlContent) throws SAXException,
			IOException, Exception {

		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
		factory.setNamespaceAware(true);// 否则无法识别namespace
		return factory.newDocumentBuilder().parse(new InputSource(new StringReader(xmlContent)));
	}

	public static Element getSingleElement(Element p_element, String p_name){
		NodeList list = p_element.getElementsByTagName(p_name);
	    if(list != null && list.getLength() > 0){
	    	return (Element) list.item(0);
	    }
	    return null;
	}
	
	public static String getInnerText(Element p_element){
		NodeList tmpChildren = p_element.getChildNodes();
		if(tmpChildren != null && tmpChildren.getLength()>0){
			return p_element.getChildNodes().item(0).getNodeValue();
		}
		return "";
	}
	
	public static String getSingleElementInnerText(Element p_element, String p_name){
		Element tmpElement = getSingleElement(p_element, p_name);
		if(tmpElement != null){
			return getInnerText(tmpElement);
		}
		return "";
	}
	
	public static void setSingleElementInnerText(Document p_doc, Element p_element, String p_name, String p_value){
		Element tmpElement = getSingleElement(p_element, p_name);
		if(tmpElement != null && p_value != null){
			setInnerText(p_doc, tmpElement, p_value);
		}
	}
	
	public static void setInnerText(Document p_doc, Element p_element, String p_value){
		NodeList tmpChildren = p_element.getChildNodes();
		if(tmpChildren != null && tmpChildren.getLength()>0){
			p_element.getChildNodes().item(0).setNodeValue(p_value);
		}
		else{
			Text tmpText = p_doc.createTextNode(p_value);
			p_element.appendChild(tmpText);
		}
	}
	
	public static Document loadXml(String p_filename) throws Exception{
		File tmpFile = new File(p_filename);
		if(tmpFile.exists()){
			DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
			DocumentBuilder builder = factory.newDocumentBuilder();
		    Document document = builder.parse(tmpFile);
		    return document;
		}
		else{
			return null;
		}
	}

	public static String toFormatedXML(Document object) throws Exception {
		Document doc = (Document) object;
		TransformerFactory transFactory = TransformerFactory.newInstance();
		Transformer transFormer = transFactory.newTransformer();
		transFormer.setOutputProperty(OutputKeys.ENCODING, "GBK");
		DOMSource domSource = new DOMSource(doc);

		StringWriter sw = new StringWriter();
		StreamResult xmlResult = new StreamResult(sw);

		transFormer.transform(domSource, xmlResult);

		return sw.toString();

	}
}
